#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <unordered_map>
#include <vector>

/**
 * PAT A 1143 Lowest Common Ancestor
 * Sequential implentation exceeds memory limit on 3 cases. Link implementation
 * timeouts on 1 case.
 * See https://blog.csdn.net/liuchuo/article/details/79618849 for solution that
 * passes all cases.
 */

static const int EMPTY = -1;

struct Node {
    int value;
    int depth;
    int parent;

    Node(int value, int depth, int parent)
        : value(value), depth(depth), parent(parent) {}

    bool operator<(const Node &other) const {
        if (depth != other.depth)
            return depth < other.depth;
        else
            return value < other.value;
    }
};

std::unordered_map<int, Node> nodes;

void build(int *pre, int len, int parent, int depth) {
    // Handle empty tree
    if (len == 0) return;

    // Create root node of current tree
    int val = pre[0];
    nodes.insert(std::pair<int, Node>(val, Node(val, depth, parent)));

    // Split tree
    int leftLen = 0;
    for (int i = 1; i < len; i++) {
        if (pre[i] < val)
            leftLen++;
        else
            break;
    }

    // Create left and right subtree
    int rightLen = len - leftLen - 1;
    build(pre + 1, leftLen, val, depth + 1);
    build(pre + (leftLen + 1), rightLen, val, depth + 1);
}

Node *find(int target) {
    std::unordered_map<int, Node>::iterator iter = nodes.find(target);
    if (iter == nodes.end())
        return NULL;
    else
        return &iter->second;
}

void findLca(int firstVal, int secondVal) {
    // Find two elements in the tree
    Node *firstNode = find(firstVal);
    Node *secondNode = find(secondVal);
    if (firstNode == NULL && secondNode == NULL) {
        printf("ERROR: %d and %d are not found.\n", firstVal, secondVal);
        return;
    }
    if (firstNode == NULL) {
        printf("ERROR: %d is not found.\n", firstVal);
        return;
    }
    if (secondNode == NULL) {
        printf("ERROR: %d is not found.\n", secondVal);
        return;
    }

    // Move up to find ancestors
    int firstAnc = firstVal, secondAnc = secondVal;
    while (true) {
        if (firstAnc == secondAnc) break;
        firstNode = find(firstAnc);
        secondNode = find(secondAnc);
        if (*firstNode < *secondNode)
            secondAnc = secondNode->parent;
        else
            firstAnc = firstNode->parent;
    }
    if (firstAnc != firstVal && secondAnc != secondVal)
        printf("LCA of %d and %d is %d.\n", firstVal, secondVal, firstAnc);
    else if (firstAnc != firstVal)
        printf("%d is an ancestor of %d.\n", secondVal, firstVal);
    else
        printf("%d is an ancestor of %d.\n", firstVal, secondVal);
}

int main() {
    // Read keys
    int nPairs, nKeys;
    scanf("%d %d", &nPairs, &nKeys);
    std::vector<int> preOrder(nKeys, 0);
    for (int i = 0; i < nKeys; i++) scanf("%d", &preOrder[i]);

    // Create tree
    build(&preOrder[0], preOrder.size(), 0, EMPTY);
    preOrder.clear();

    // Read pairs and find LCA
    for (int i = 0; i < nPairs; i++) {
        int first, second;
        scanf("%d %d", &first, &second);
        findLca(first, second);
    }
    return 0;
}